package pictureseditor.factories;

import pictureseditor.ParameterPicker;
import pictureseditor.effects.ColorEnum;
import pictureseditor.effects.Effect;
import pictureseditor.effects.EffectEnum;
import pictureseditor.effects.EffectSequential;
import pictureseditor.effects.effectsimpl.EffectAddNoize;
import pictureseditor.effects.effectsimpl.EffectAverage;
import pictureseditor.effects.effectsimpl.EffectBlackAndWhite;
import pictureseditor.effects.effectsimpl.EffectBlur;
import pictureseditor.effects.effectsimpl.EffectColorize;
import pictureseditor.effects.effectsimpl.EffectColorizedMozaic1;
import pictureseditor.effects.effectsimpl.EffectColorizedMozaic2;
import pictureseditor.effects.effectsimpl.EffectContrastBooster;
import pictureseditor.effects.effectsimpl.EffectCutter;
import pictureseditor.effects.effectsimpl.EffectDrawing;
import pictureseditor.effects.effectsimpl.EffectFilter;
import pictureseditor.effects.effectsimpl.EffectGradientMozaic;
import pictureseditor.effects.effectsimpl.EffectHorizontalMirror;
import pictureseditor.effects.effectsimpl.EffectInShape;
import pictureseditor.effects.effectsimpl.EffectMonochromatic;
import pictureseditor.effects.effectsimpl.EffectPastel;
import pictureseditor.effects.effectsimpl.EffectPixelize;
import pictureseditor.effects.effectsimpl.EffectReverseColors;
import pictureseditor.effects.effectsimpl.EffectRotation;
import pictureseditor.effects.effectsimpl.EffectShadow;
import pictureseditor.effects.effectsimpl.EffectSimpleMozaic;
import pictureseditor.effects.effectsimpl.EffectVerticalMirror;
import pictureseditor.effects.filters.Filter;
import pictureseditor.effects.filters.FilterEnum;
import pictureseditor.effects.filters.filtersimpl.FilterEdgeDetection;
import pictureseditor.effects.filters.filtersimpl.FilterEmbossing;
import pictureseditor.effects.filters.filtersimpl.FilterRelief;
import pictureseditor.effects.filters.filtersimpl.FilterShine;
import pictureseditor.effects.filters.filtersimpl.FilterSurex;
import pictureseditor.effects.shapes.ShapeCircle;
import pictureseditor.effects.shapes.ShapeRectangle;
import pictureseditor.exceptions.EffectNotCreatedException;
import pictureseditor.exceptions.NullImageException;
import pictureseditor.exceptions.NullParameterValueException;
import pictureseditor.images.Image;

public class EffectFactory implements EffectFactoryInterface {
	
	@Override
	public Effect buildEffect(EffectEnum type, Image image) throws NullImageException, EffectNotCreatedException {
		if(image==null) throw new NullImageException("effect can't be apply on null image");
		Effect effect = null;
		int parameter = 0;
		switch(type) {
		    case ADDNOIZE:
				try { 
					parameter = new ParameterPicker("Noize Level", 0, 100, EffectEnum.ADDNOIZE, image).askForValue();
					effect = new EffectAddNoize(image, parameter); 
				} catch (NullParameterValueException e) { 
					System.out.println(e); 
					throw new EffectNotCreatedException("effect can't be created");
				} 
				break;
			case BLUR:
				try { 
					parameter = new ParameterPicker("Blur Level", 0, 100, EffectEnum.BLUR, image).askForValue();
					effect = new EffectBlur(image, parameter);
				} catch (NullParameterValueException e) { 
					System.out.println(e); 
					throw new EffectNotCreatedException("effect can't be created");
				} 
				break;
			case PIXELIZE:
				try { 
					parameter = new ParameterPicker("Pixels size", 1, 31, EffectEnum.PIXELIZE, image).askForValue();
					effect = new EffectPixelize(image, parameter);
				} catch (NullParameterValueException e) { 
					System.out.println(e); 
					throw new EffectNotCreatedException("effect can't be created");
				} 
				break;
			case MONOCHROMATIC:
				try { 
					parameter = new ParameterPicker("Monochrome level", 0, 255, EffectEnum.MONOCHROMATIC, image).askForValue();
					effect = new EffectMonochromatic(image, parameter);
				} catch (NullParameterValueException e) { 
					System.out.println(e); 
					throw new EffectNotCreatedException("effect can't be created");
				} 
				break;
			case AVERAGE:
				effect = new EffectAverage(image); break;
			case PASTEL:
				effect = new EffectPastel(image); break;
			case DRAWING:
				effect = new EffectDrawing(image); break;
			case CUTTER:
				effect = new EffectCutter(image, false); break;
			case SIMPLEMOZAIC:
				effect = new EffectSimpleMozaic(image); break;
			case COLORIZEDMOZAIC1:
				effect = new EffectColorizedMozaic1(image); break;
			case COLORIZEDMOZAIC2:
				effect = new EffectColorizedMozaic2(image); break;
			case GRADIENTMOZAIC:
				effect = new EffectGradientMozaic(image); break;
			case INCIRCLE:
				effect = new EffectInShape(image, new ShapeCircle()); break;
			case INRECTANGLE:
				effect = new EffectInShape(image, new ShapeRectangle()); break;
			case REVERSECOLOR:
				effect = new EffectReverseColors(image); break;
			case BLACKANDWHITE:
				effect = new EffectBlackAndWhite(image); break;
			case CONTRAST:
				effect = new EffectContrastBooster(image); break;
			case SEQUENTIAL:
				effect = new EffectSequential(image); break;
			case ROTATION:
				effect = new EffectRotation(image); break;
			case VERTICALMIRROR:
				effect = new EffectVerticalMirror(image); break;
			case HORIZONTALMIRROR:
				effect = new EffectHorizontalMirror(image); break;
			case SHADOW:
				effect = new EffectShadow(image); break;
			default:
				break;
		}
		return effect;
	}

	@Override
	public Effect buildEffect(EffectEnum type, Image image, int param) throws NullImageException, EffectNotCreatedException {
		if(image==null) throw new NullImageException("effect can't be apply on null image");
		Effect effect = null;
		switch(type) {
		case ADDNOIZE:
			effect = new EffectAddNoize(image, param); break;
		case BLUR:
			effect = new EffectBlur(image, param); break;
		case PIXELIZE:
			effect = new EffectPixelize(image, param); break;
		case MONOCHROMATIC:
			effect = new EffectMonochromatic(image, param); break;
		default:
			effect = buildEffect(type, image); break;
		}
		return effect;
	}
	
	@Override
	public Effect buildEffect(EffectEnum type, Image image, ColorEnum color) throws NullImageException, EffectNotCreatedException {
		if(image==null) throw new NullImageException("effect can't be apply on null image");
		Effect effect = null;
		switch(type) {
		case COLORIZE:
			effect = new EffectColorize(image, color); break;
		default:
			buildEffect(type, image); break;
		}
		return effect;
	}
	
	@Override
	public Effect buildEffect(EffectEnum type, Image image, int r, int g, int b) throws NullImageException, EffectNotCreatedException {
		if(image==null) throw new NullImageException("effect can't be apply on null image");
		Effect effect = null;
		switch(type) {
		case COLORIZE:
			effect = new EffectColorize(image, r, g, b); break;
		default:
			buildEffect(type, image); break;
		}
		return effect;
	}
	
	@Override
	public Effect buildEffect(EffectEnum type, Image image, boolean preview) throws NullImageException, EffectNotCreatedException {
		if(image==null) throw new NullImageException("effect can't be apply on null image");
		Effect effect = null;
		switch(type) {
		case CUTTER:
			effect = new EffectCutter(image, preview); break;
		default:
			buildEffect(type, image); break;
		}
		return effect;
	}

	@Override
	public EffectFilter buildEffect(FilterEnum type, Image image)  throws NullImageException, EffectNotCreatedException {
		if(image==null) throw new NullImageException("effect can't be apply on null image");
		EffectFilter effect = null;
		switch(type) {
			case EDGEDETECTION:
				effect = new EffectFilter(image, new FilterEdgeDetection()); break;
			case EMBOSSING:
				effect = new EffectFilter(image, new FilterEmbossing()); break;
			case SHINE:
				effect = new EffectFilter(image, new FilterShine()); break;
			case RELIEF:
				effect = new EffectFilter(image, new FilterRelief()); break;
			case SUREX:
				effect = new EffectFilter(image, new FilterSurex()); break;
			default: break;
		}
		return effect;
	}

	@Override
	public Effect buildEffect(Filter type, Image image) throws NullImageException, EffectNotCreatedException {
		if(image==null) throw new NullImageException("effect can't be apply on null image");
		return new EffectFilter(image, type);
	}

}
